#include "util/object.h"
#include "util/exception.h"

NS_UTIL_BEGIN

// ObjectData
ObjectData::ObjectData():refCount(0)
{
}

ObjectData::~ObjectData()
{
	if(refCount!=0)
	{
		throw runtime_error("Cannot release an ObjectData!");
	}
}

ObjectData* ObjectData::Clone()const
{
	return NULL;
}

// ObjectPtrBase
ObjectPtrBase::ObjectPtrBase():ptr(NULL)
{}

ObjectPtrBase::ObjectPtrBase(ObjectPtrBase& another_ptr):ptr(another_ptr.ptr)
{
	incref();
}

ObjectPtrBase::ObjectPtrBase(ObjectData* another_ptr):ptr(another_ptr)
{
	incref();
}

void ObjectPtrBase::incref()
{
	if(!ptr)
	{
		// Do nothing
	}else
	{
		ptr->refCount++;		// increase reference count
	}
}

void ObjectPtrBase::decref()
{
	if(!ptr)
	{
		// Do nothing
	}else
	{
		ptr->refCount--;			// decrease reference count
		if(ptr->refCount==0)		// free memory
		{
			delete ptr;
			ptr = NULL;
		}
	}
}

ObjectPtrBase::operator bool()const
{
	return ptr!=NULL;
}

ObjectPtrBase& ObjectPtrBase::operator= (ObjectPtrBase& data)
{
	decref();
	ptr = data.ptr;
	incref();
	return *this;
}

ObjectPtrBase& ObjectPtrBase::operator= (ObjectData* data)
{
	
	decref();
	ptr = data;
	incref();
	return *this;
}

ObjectPtrBase::operator ObjectData* ()
{
	return ptr;
}

ObjectData* ObjectPtrBase::get()
{
	return ptr;
}

const ObjectData* ObjectPtrBase::get() const
{
	return ptr;
}

ObjectPtrBase::~ObjectPtrBase()
{
	decref();
}

NS_UTIL_END